package cn.edu.tju.wallet.domain;

import cn.edu.tju.core.model.BaseEntity;
import jakarta.persistence.*;
import java.math.BigDecimal;

/**
 * 提现规则实体（充血模型）
 * 包含提现规则数据和规则相关的业务逻辑
 */
@Entity
@Table(name = "withdraw_rules")
public class WithdrawRule extends BaseEntity {

    @Column(name = "name", nullable = false, length = 100)
    private String name; // 规则名称

    @Column(name = "fee_rate", precision = 5, scale = 4, nullable = false)
    private BigDecimal feeRate; // 手续费率

    @Column(name = "min_fee", precision = 19, scale = 2)
    private BigDecimal minFee; // 最低手续费

    @Column(name = "max_fee", precision = 19, scale = 2)
    private BigDecimal maxFee; // 最高手续费

    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private RuleStatus status = RuleStatus.ACTIVE; // 规则状态

    @Column(name = "priority", nullable = false)
    private Integer priority = 0; // 优先级

    @Column(name = "comment", length = 500)
    private String comment; // 规则描述

    // ============================================
    // 构造函数
    // ============================================

    public WithdrawRule() {}

    public WithdrawRule(String name, BigDecimal feeRate) {
        this.name = name;
        this.feeRate = feeRate;
        this.status = RuleStatus.ACTIVE;
        this.priority = 0;
    }

    public WithdrawRule(String name, BigDecimal feeRate, String comment) {
        this.name = name;
        this.feeRate = feeRate;
        this.comment = comment;
        this.status = RuleStatus.ACTIVE;
        this.priority = 0;
    }

    // ============================================
    // 核心业务方法
    // ============================================

    /**
     * 计算手续费（充血模型：规则自己计算手续费）
     * @param amount 提现金额
     * @return 手续费
     */
    public BigDecimal calculateFee(BigDecimal amount) {
        if (this.status != RuleStatus.ACTIVE)
            return BigDecimal.ZERO;

        BigDecimal fee = amount.multiply(this.feeRate);

        // 应用最低手续费
        if (this.minFee != null && fee.compareTo(this.minFee) < 0)
            fee = this.minFee;

        // 应用最高手续费
        if (this.maxFee != null && fee.compareTo(this.maxFee) > 0)
            fee = this.maxFee;

        return fee;
    }

    /**
     * 判断规则是否激活
     * @return 是否激活
     */
    public boolean isActive() {
        return this.status == RuleStatus.ACTIVE;
    }

    /**
     * 计算实际到账金额（提现金额 - 手续费）
     * @param amount 提现金额
     * @return 实际到账金额
     */
    public BigDecimal calculateActualAmount(BigDecimal amount) {
        BigDecimal fee = calculateFee(amount);
        return amount.subtract(fee);
    }

    /**
     * 计算手续费率（百分比形式）
     * @return 手续费率
     */
    public BigDecimal getFeeRatePercentage() {
        return this.feeRate.multiply(BigDecimal.valueOf(100));
    }

    /**
     * 判断是否有手续费上限
     * @return 是否有手续费上限
     */
    public boolean hasMaxFee() {
        return this.maxFee != null;
    }

    /**
     * 判断是否有手续费下限
     * @return 是否有手续费下限
     */
    public boolean hasMinFee() {
        return this.minFee != null;
    }

    /**
     * 获取手续费计算规则描述
     * @return 手续费规则描述
     */
    public String getFeeRuleDescription() {
        StringBuilder sb = new StringBuilder();
        sb.append("费率: ").append(getFeeRatePercentage()).append("%");

        if (hasMinFee()) {
            sb.append("，最低: ").append(this.minFee).append("元");
        }
        if (hasMaxFee()) {
            sb.append("，最高: ").append(this.maxFee).append("元");
        }

        return sb.toString();
    }

    /**
     * 计算在不同提现金额下的手续费
     * @param amounts 提现金额列表
     * @return 手续费列表
     */
    public java.util.List<BigDecimal> calculateFeesForAmounts(java.util.List<BigDecimal> amounts) {
        return amounts.stream()
                     .map(this::calculateFee)
                     .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 计算在不同提现金额下的实际到账金额
     * @param amounts 提现金额列表
     * @return 实际到账金额列表
     */
    public java.util.List<BigDecimal> calculateActualAmounts(java.util.List<BigDecimal> amounts) {
        return amounts.stream()
                     .map(this::calculateActualAmount)
                     .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 激活规则
     * @return 当前规则对象
     */
    public WithdrawRule activate() {
        this.status = RuleStatus.ACTIVE;
        return this;
    }

    /**
     * 停用规则
     * @return 当前规则对象
     */
    public WithdrawRule deactivate() {
        this.status = RuleStatus.INACTIVE;
        return this;
    }

    /**
     * 设置手续费上下限
     * @param minFee 最低手续费
     * @param maxFee 最高手续费
     * @return 当前规则对象
     */
    public WithdrawRule setFeeLimits(BigDecimal minFee, BigDecimal maxFee) {
        this.minFee = minFee;
        this.maxFee = maxFee;
        return this;
    }

    /**
     * 设置优先级
     * @param priority 优先级
     * @return 当前规则对象
     */
    public WithdrawRule setPriority(Integer priority) {
        this.priority = priority;
        return this;
    }

    /**
     * 验证规则参数的有效性
     * @throws IllegalArgumentException 当参数无效时
     */
    public void validate() {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("规则名称不能为空");
        }
        if (feeRate == null || feeRate.compareTo(BigDecimal.ZERO) < 0 || feeRate.compareTo(BigDecimal.ONE) > 0) {
            throw new IllegalArgumentException("手续费率必须在0到1之间");
        }
        if (minFee != null && minFee.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("最低手续费不能为负数");
        }
        if (maxFee != null && maxFee.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("最高手续费不能为负数");
        }
        if (minFee != null && maxFee != null && minFee.compareTo(maxFee) > 0) {
            throw new IllegalArgumentException("最低手续费不能高于最高手续费");
        }
    }

    /**
     * 判断是否可以删除规则
     * @return 是否可以删除
     */
    public boolean canBeDeleted() {
        return this.status == RuleStatus.INACTIVE;
    }

    /**
     * 获取提现规则详细信息
     * @return 规则描述
     */
    public String getDescription() {
        if (comment != null && !comment.trim().isEmpty()) {
            return comment;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(name).append("：");
        sb.append(getFeeRuleDescription());
        sb.append("，状态：").append(isActive() ? "激活" : "停用");
        return sb.toString();
    }

    /**
     * 计算手续费率对应的年利率（假设一天提现一次）
     * @return 年利率
     */
    public BigDecimal calculateAnnualFeeRate() {
        // 简化计算：日费率 * 365
        return this.feeRate.multiply(BigDecimal.valueOf(365))
                          .multiply(BigDecimal.valueOf(100));
    }

    /**
     * 判断是否免手续费
     * @return 是否免手续费
     */
    public boolean isFeeFree() {
        return this.feeRate.compareTo(BigDecimal.ZERO) == 0;
    }

    //规则状态
    public enum RuleStatus {
        ACTIVE,     // 激活
        INACTIVE    // 未激活
    }

    // ============================================
    // Getter and Setter
    // ============================================

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getFeeRate() {
        return feeRate;
    }

    public void setFeeRate(BigDecimal feeRate) {
        this.feeRate = feeRate;
    }

    public BigDecimal getMinFee() {
        return minFee;
    }

    public void setMinFee(BigDecimal minFee) {
        this.minFee = minFee;
    }

    public BigDecimal getMaxFee() {
        return maxFee;
    }

    public void setMaxFee(BigDecimal maxFee) {
        this.maxFee = maxFee;
    }

    public RuleStatus getStatus() {
        return status;
    }

    public void setStatus(RuleStatus status) {
        this.status = status;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }
}

